home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / uupc 3.1 / Files in common / pcmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-29  |  28.6 KB  |  1,168 lines  |  [TEXT/KAHL]

  1.  
  2. /*         pcmail.c
  3.  
  4.  
  5.  
  6.         copyright (C) 1987 Stuart Lynne
  7.  
  8.         Copying and use of this program are controlled by the terms of the
  9.         Free Software Foundations GNU Emacs General Public License.
  10.  
  11.             Portions Copyright © David Platt, 1992, 1991.  All Rights Reserved
  12.             Worldwide.
  13.  
  14.  
  15.         version        0.1        March 31/1987
  16.  
  17.  
  18. pcmail
  19.  
  20.         pcmail address1 address2 ... < the.message
  21.  
  22. description
  23.  
  24.     An 822 compatible (hopefully) mail delivery system for pc's.
  25.  
  26.     Designed for delivering mail on a pc based system. It will put
  27.     local mail (ie, not @ or ! in address) into files in the default
  28.     mail directory.
  29.  
  30.     If remote it will put into an outgoing mailbag in the default mail
  31.     directory. Performs a simple bundling of mail messages into one
  32.     file with arguments prepended as To: arg header lines. And adds a
  33.     Message-Lines: header which gives the number of lines in the
  34.     content part of the message (after the first blank line).
  35.  
  36.         pcmail john jack jill@xyz.uucp < afile
  37.  
  38.         To: john
  39.         To: jack
  40.         To: jill@xyz.uucp
  41.         X-Message-Lines: ?????
  42.         Content-Length: ?????
  43.  
  44.         ...
  45.         ...
  46.         ...
  47.  
  48.     Content-Length: is used without X- prepended to be compatible with AT&T
  49.     Mail bundles. This is not 822 compatible per se, but is allowed.
  50.  
  51.     It also adds the from From and Date lines. Subject: lines may be inserted
  52.     by placing them at the beginning of the message.
  53.  
  54.     A Unix version should lock the /usr/mail/mailbag file.
  55.  
  56.     Another program called rpcmail will unbundle the files created by
  57.     pcmail and deliver each message to the local rmail. So conceptually
  58.  
  59.         (pcmail ..... < ...; pcmail .... < ...) | sz -> rz | rpcmail
  60.  
  61.     would deliver remote messages intact.
  62.  
  63. environment variables
  64.  
  65.     The following evironment variables are used:
  66.  
  67.         MAILBOX        current user's mailbox,     "stuart"
  68.         NAME        current user's name,         "Stuart Lynne"
  69.         DOMAIN        domain of this machine,     "slynne.mac.van-bc.can"
  70.         MAILDIR        where is mail kept,            "mpw:mail"
  71.         ALIAS        user's mail aliases            ".alias"
  72.         MBOX        filewhere is mail kept        ""                    BH-C
  73. 112
  74. compiling
  75.  
  76.     Compiled by itself it will operate as a standalone program. If the
  77.     compiler option:
  78.  
  79.         -DNOMAIN
  80.  
  81.     is used, it will compile as a routine:
  82.  
  83.         pcmail (argc, argv)
  84.         char **argv;
  85.         int argc;
  86.  
  87.     and can be used internally in other programs.
  88.  
  89.  
  90. Customization
  91.  
  92.     PCMAIL        mailbag for remote mail
  93.     FAKEUUX        emulate uux, make appropriate files in SPOOLDIR
  94.  
  95.     RMAIL        rmail
  96.  
  97.     DEBUG1        first level Debug trace
  98.  
  99.  
  100. */
  101.  
  102. #include <stdio.h>
  103. #ifdef     THINK_C
  104. #include <unix.h>
  105. #endif
  106.  
  107. #include "pcmail.h"
  108.  
  109. #include "host.h"
  110. #include "ndir.h"
  111.  
  112. #ifdef THINK_C                    /* BH-C */
  113. #include "script.h"                /* BH-C */
  114. #endif THINK_C                    /* BH-C */
  115.  
  116. /*
  117. #endif
  118. */
  119.  
  120. #define FORWARD        "Forward to"
  121.  
  122.  
  123. #define    SBUFSIZ        124
  124. #define RMAILCMDSIZ        120
  125.  
  126.  
  127. FILE   *mailfile;
  128. #ifdef Upgrade
  129. FILE   *aliasfile;
  130. #endif Upgrade
  131. FILE   *tempfile;
  132.  
  133. char    buf[BUFSIZ];
  134. char    miscbuff[255];
  135. long int lines = 0;
  136. long int bytes = 0;
  137. long int sequence = 0;
  138.  
  139. time_t tloc;
  140. char chartime[128];    /* current time in characters */
  141. char *thetime;
  142.  
  143. char    tfilename[255];
  144. char    mfilename[255];
  145. char    mailsent[255];
  146.  
  147. #ifdef Upgrade
  148. char    afilename[255];
  149. #endif Upgrade
  150.  
  151. int local = TRUE;
  152.  
  153. char viaremote[BUFSIZ] = "";
  154. char thisremote[BUFSIZ] = "";
  155.  
  156. char     remotes[BUFSIZ];
  157.  
  158. char gotitfrom[BUFSIZ] = "";
  159. char gotfromuser[BUFSIZ] = "";
  160.  
  161.  
  162. char uucp[] = "uucp";
  163.  
  164. char *fgets();
  165. int fputs();
  166.  
  167. #ifdef NOMAIN
  168.  
  169. #ifdef RMAIL
  170. #define main    rmail
  171. #else
  172. #define    main    lmail
  173. #endif
  174.  
  175. #define exit    return
  176.  
  177. extern int debuglevel;
  178.  
  179. #else
  180. int debuglevel;
  181. #endif
  182.  
  183. #ifndef RMAIL
  184. char    Subject[132] = "";
  185. #endif
  186.  
  187. char *mcurdir;
  188. char s_mcurdir[128];    /* current directory path (save malloc call) */
  189. char * getcwd();
  190. int chdir();
  191.  
  192. #ifdef MULTIFINDER
  193. #define UnImplTrapNum 0x9F
  194. #define StripAddressTrapNum 0x55
  195.  
  196. /* #include "pcmail.proto.h"    BH-C */
  197.  
  198. #include "pcmail.proto.h"
  199. long int Strip(long int);
  200. long int Strip(long int foo)
  201. {
  202.     if (NGetTrapAddress( StripAddressTrapNum,OSTrap) !=
  203.          NGetTrapAddress(UnImplTrapNum,ToolTrap)) {
  204.         return (long int) StripAddress((void *) foo);
  205.     } else {
  206.         return (Lo3Bytes & (long int) foo);
  207.      }
  208. }    
  209. #endif
  210.  
  211. int
  212. sendit(int argc, char **argv, char *addr, char *remotes) {
  213.     int s1, s2;
  214.     int err = 1;
  215.     char routelist[BUFSIZ], tryroute[BUFSIZ], composite[BUFSIZ];
  216.     
  217.     char *bang, *atsign, *percent;
  218.     char *addx;                    /* BH-C */
  219.  
  220. /*
  221.     Recognize and strip off our own nodename and domain name, whether by l@nd, s%, or sk!
  222. */
  223.  
  224.     strcpy(composite, nodename);
  225.     strcat(composite, ".");
  226.     strcat(composite, domain);
  227.  
  228. #ifdef NOTDEF
  229.     fprintf(stderr, "Address %s, node %s, domain %s\n", addr, nodename, domain);
  230.     fflush(stderr);
  231. #endif
  232.     
  233.     atsign = strrchr(addr, '@');
  234.     
  235.     while (atsign != NULL && (IUMagIDString(domain, atsign+1, strlen(domain), strlen(atsign+1)) == 0 ||
  236.                                             IUMagIDString(composite, atsign+1, strlen(composite), strlen(atsign+1)) == 0 ||
  237.                                             IUMagIDString(nodename, atsign+1, strlen(nodename), strlen(atsign+1)) == 0))  {
  238.         *atsign = '\0';
  239.         atsign = strrchr(addr, '@');
  240.     }
  241.     
  242.     bang = strchr(addr, '!');
  243.  
  244.     while (bang != NULL && (IUMagIDString(nodename, addr, strlen(nodename), bang-addr) == 0 ||
  245.                                           IUMagIDString(domain, addr, strlen(domain), bang-addr) == 0  ||
  246.                                           IUMagIDString(composite, addr, strlen(composite), bang-addr) == 0)) {
  247. #ifdef NOTDEF
  248.             SysBeep(1);
  249. #endif
  250.         addr = bang+1;
  251.         bang = strchr(addr, '!');
  252.     }
  253.     
  254.     percent = strrchr(addr, '%');
  255.     
  256.     while (percent != NULL && (IUMagIDString(domain, percent+1, strlen(domain), strlen(percent+1)) == 0 ||
  257.                                                IUMagIDString(composite, percent+1, strlen(composite), strlen(percent+1)) == 0)) {
  258.         *percent = '\0';
  259.         percent = strrchr(addr, '%');
  260.     }
  261.     
  262.     
  263.     if(atsign || bang || percent) {
  264.         if ( debuglevel > 5 )
  265.             fprintf( stderr, "pcmail: send to remote\n" );
  266.         
  267.         if (atsign || percent) {
  268.             /* BH-C v */
  269.             if (atsign) {
  270.                 addx = atsign + 1;
  271.                 sprintf(routelist, ",%s,", routevia);            /* domain names must be lowercase */
  272.                 sprintf(tryroute, ",%s:", addx);
  273.                 for (addx = tryroute; *addx != '\0'; addx++)    {/* make address lower case */
  274.                     if ( isupper(*addx) )
  275.                         *addx = *addx + 32;
  276.                 }
  277.                 atsign = tryroute; addx = NULL;
  278.                 while ( (atsign != NULL) && ((addx = strstr(routelist,atsign)) == NULL) ) { /* find partial domain */
  279.                     atsign = strchr(atsign,'.');
  280.                     *atsign  = ',';
  281.                 }
  282.                 strcpy(thisremote, mailserv);
  283.                 if (addx != NULL) {
  284.                     addx++; /* skip ',' */
  285.                     addx = strchr(addx, ':');
  286.                     atsign = strchr(addx, ',');
  287.                     if (addx != NULL) {
  288.                         addx++;
  289.                         if (atsign != NULL) {
  290.                             if (addx < atsign) {
  291.                                 strncpy(thisremote, addx,atsign - addx);
  292.                                 thisremote[atsign - addx] = '\0';
  293.                             }
  294.                         } else
  295.                             strcpy(thisremote,addx);
  296.                     }
  297.                 }
  298.             } else
  299.             /* BH-C ^ */
  300.             strcpy(thisremote, mailserv);
  301.         } else {
  302.             strncpy(thisremote, addr, bang - addr);
  303.             thisremote[bang - addr] = '\0';
  304.             sprintf(routelist, ",%s,", routevia);
  305.             sprintf(tryroute, ",%s,", thisremote);
  306.             if (strstr(routelist, tryroute) == NULL) {
  307.                 /* BH-C v */
  308.                 sprintf(tryroute, ":%s,", thisremote);
  309.                 if (strstr(routelist, tryroute) == NULL)
  310.                 /* BH-C ^ */
  311.                 strcpy(thisremote, mailserv);
  312.             }
  313.         }
  314.  
  315.         /* BH-C v */
  316.         if ( debuglevel > 4 )
  317.             fprintf( stderr, "pcmail: viaremote - %s\n",thisremote );
  318.         /* BH-C ^ */
  319.  
  320.         s1 = strlen(remotes);
  321.         s2 = strlen(addr);
  322.  
  323.         /* can we cram one more address on line?  same host? */
  324.         if( s1 > 0 && ((s1 + s2 + 1) > RMAILCMDSIZ || strcmp(thisremote, viaremote) != 0)) {
  325.             /* dump it then, too bad */
  326.             err &= sendone(argc, argv, remotes, TRUE);
  327.             remotes[0] = '\0';
  328.             GetSequenceNumber(); /* update seq # for new sending */
  329.         }
  330.  
  331.         /* add *argvec to list of remotes */
  332.         strcat(remotes, " ");
  333.         strcat(remotes, addr);
  334.         strcpy(viaremote, thisremote);
  335.     }
  336.     else {
  337.         if (debuglevel > 5)
  338.             fprintf(stderr, "pcmail: calling sendone %s\n", addr);
  339.         err &= sendone(argc, argv, addr, FALSE);
  340.     }
  341.     return (err);
  342. }
  343.  
  344. main(int argc, char **argv) {
  345.     long int position;
  346.     register int header = 1;
  347.     register int amount;
  348.  
  349.     register int argcount;
  350.     register char **argvec;
  351.     int remote;
  352.     int err = 1;
  353.     DIR    *spoolDir;
  354. #ifdef Upgrade
  355.     int gotalias;
  356.     char *bang, *atsign, *percent;
  357.     char *addr, addrbuf[256];
  358. #endif Upgrade
  359.  
  360. #ifndef NOMAIN
  361.     /* get environment var's */
  362.     err = 1;
  363.     HOSTINIT;
  364.     loadenv();
  365.  
  366.      if (argc <= 1) {
  367.         fprintf( stderr, "pcmail usage: pcmail addresses < message\n" );
  368.         exit(1);
  369.     }
  370.     debuglevel = 1;
  371.  
  372. #endif
  373. #ifdef RMAIL
  374.     local = FALSE;
  375. #else
  376.     local = TRUE;
  377. #endif
  378.  
  379.     if ( debuglevel > 5 ) {
  380.         fprintf( stderr, "pcmail: argc %d ", argc );
  381.         argcount = argc;
  382.         argvec = argv;
  383.         while (argcount--) {
  384.             fprintf( stderr, " \"%s\"", *argvec++ );
  385.             }
  386.         fprintf( stderr, "\n" );
  387.  
  388.         tloc = time((time_t *)NULL );
  389.         thetime = ctime(&tloc);
  390.         fprintf( stderr, "thetime: %s\n",thetime );
  391.     }
  392.  
  393. #ifdef MSDOS
  394.      mcurdir = getcwd( s_mcurdir, sizeof(s_mcurdir) );
  395. #else
  396.     mcurdir = getcwd( s_mcurdir, sizeof(s_mcurdir) );
  397. #endif
  398.     chdir( spooldir );
  399.     /*
  400.     spoolDir = opendir (spooldir);
  401.     */
  402.     
  403.     GetSequenceNumber();
  404.  
  405.     /* open a temporary file */
  406.     /* sprintf( tfilename, TFILENAME, sequence ); */
  407.      sprintf( tfilename, TFILENAME, sequence );
  408.      mkfilename( miscbuff, tempdir, tfilename );
  409.      if (*tempdir != SEPCHAR)
  410.          mkfilename(tfilename, mcurdir, miscbuff);
  411.      else strcpy(tfilename, miscbuff);
  412.  
  413.      if ( debuglevel > 5 )
  414.          fprintf( stderr, "pcmail: opening %s\n", tfilename );
  415.  
  416.     tempfile = FOPEN( tfilename, "w", 't' );
  417.      if (tempfile == (FILE *)NULL)  {
  418.         fprintf( stderr, "pcmail: can't open %s\n", tfilename );
  419.         exit(1);
  420.     }
  421.  
  422.     /* copy stdin to tempfile, counting content lines and bytes */
  423.     header = 1;
  424.     while (fgets( buf, BUFSIZ - 1, stdin ) != (char *)NULL) {
  425.         if (header != 0) {
  426.             if (strlen( buf ) == 1) {
  427.                 header = 0;
  428.                 fprintf( tempfile, "\n" );
  429.                 continue;
  430.             }
  431.             /*
  432.             else if (strchr( buf, ':' ) == NULL) {
  433.                 header = 0;
  434.                 fprintf( tempfile, "\n" );
  435.             }
  436.             */
  437.         }
  438.         if (header == 0) {
  439.             lines++;
  440.             bytes += strlen( buf );
  441.         }
  442.         fputs( buf, tempfile );
  443. #ifdef MULTIFINDER
  444.         Check_Events(0);
  445. #endif
  446.     }
  447. #ifndef RMAIL
  448.     /* copy stdin to tempfile, counting content lines and bytes */
  449.     /* get signature */
  450.     mkfilename( miscbuff, home, signature );
  451.     if (*home != SEPCHAR)
  452.          mkfilename(mfilename, mcurdir, miscbuff);
  453.      else strcpy(mfilename, miscbuff);
  454.  
  455.     if (debuglevel > 4)
  456.         fprintf( stderr, "pcmail: opening sigfile %s\n", mfilename );
  457.     mailfile = FOPEN( mfilename, "r", 't' );
  458.     if (mailfile != (FILE *)NULL) {
  459.         fputs( "\n--\n", tempfile );
  460.         while (fgets( buf, BUFSIZ - 1, mailfile ) != (char *)NULL) {
  461.             lines++;
  462.             bytes += strlen( buf );
  463.             fputs( buf, tempfile );
  464.         }
  465.         fclose( mailfile );
  466.      }
  467. #endif
  468.  
  469.      fclose( tempfile );
  470.  
  471.     if ( debuglevel > 4 ) {
  472.         fprintf( stderr, "pcmail: stdin copied to tmp %ld %ld\n",
  473.                      bytes, lines );
  474.          fprintf( stderr, "pcmail: args %d\n", argc );
  475.     }
  476.  
  477.     /* loop on args, copying to appropriate postbox,
  478.        do remote only once
  479.        remote checking is done empirically, could be better
  480.     */
  481.     remotes[0] = '\0';
  482.  
  483.  
  484. #ifndef RMAIL
  485.     if ( strcmp( argv[1], "-s" ) == SAME ) {
  486.         argv++;argv++;
  487.         argc--;argc--;
  488.         if ( argc == 0 )
  489.             return( -1 );
  490.         strcpy( Subject, *argv );
  491.         }
  492. #endif
  493.     argcount = argc;
  494.     argvec = argv;
  495.  
  496.     while (--argcount > 0) {
  497.         argvec++;
  498.         strcpy(addrbuf, *argvec);
  499.         addr = addrbuf;
  500.         if ( debuglevel > 5 )
  501.             fprintf( stderr, "pcmail: arg# %d\ %s\n",
  502.                             argcount, *argvec );
  503. /*
  504.     Recognize and strip off our own nodename and domain name, whether by l@nd, s%, or sk!
  505. */
  506.  
  507.         atsign = strrchr(addr, '@');
  508.         
  509.         while (atsign != NULL && IUMagIDString(domain, atsign+1, strlen(domain), strlen(atsign+1)) == 0) {
  510.             *atsign = '\0';
  511.             atsign = strrchr(addr, '@');
  512.         }
  513.         
  514.         bang = strchr(addr, '!');
  515.     
  516.         while (bang != NULL && (IUMagIDString(nodename, addr, strlen(nodename), bang-addr) == 0 ||
  517.                                          IUMagIDString(domain, addr, strlen(domain), bang-addr)  == 0)) {
  518.             addr = bang+1;
  519.             bang = strchr(addr, '!');
  520.         }
  521.         
  522.         percent = strrchr(addr, '%');
  523.         
  524.         while (percent != NULL && IUMagIDString(domain, percent+1, strlen(domain), strlen(percent+1)) == 0) {
  525.             *percent = '\0';
  526.             percent = strrchr(addr, '%');
  527.         }
  528.         /* get alias file */
  529.         mkfilename(miscbuff, home, alias);
  530.         if(*home != SEPCHAR)
  531.              mkfilename(afilename, mcurdir, miscbuff);
  532.          else
  533.              strcpy(afilename, miscbuff);
  534.  
  535.         if(debuglevel > 4)
  536.             fprintf(stderr, "pcmail: opening alias file %s\n", afilename);
  537.         gotalias = FALSE;
  538.         if((aliasfile=FOPEN(afilename, "r", 't')) != (FILE *)NULL) {
  539.             char str[BUFSIZ], *args[255];
  540.             int i, nargs;
  541.             char *theAlias, *newAlias;
  542. #ifdef MULTIFINDER
  543.             Handle aliasHandle;
  544.             aliasHandle = NULL;
  545. #endif
  546.             theAlias = (char *) NULL;
  547.  
  548.             while(fgets(str, BUFSIZ - 1, aliasfile) != (char *)NULL && !feof(aliasfile)) {
  549. #ifdef MULTIFINDER
  550.                 aliasHandle = NewHandle(strlen(str)+1);
  551.                 if (aliasHandle) {
  552.                     MoveHHi(aliasHandle);
  553.                     HLock(aliasHandle);
  554.                     theAlias = (char *) Strip((long int) *aliasHandle);
  555.                 } else {
  556.                     theAlias = (char *) NULL;
  557.                 }
  558. #else
  559.                 theAlias = malloc(strlen(str) + 1);
  560. #endif
  561.                 if (theAlias == (char *) NULL) {
  562.                     fprintf(stderr, "Can't get string buffer for alias!");
  563.                     break;
  564.                 }
  565.                 strcpy(theAlias, str);
  566.                 while(strlen(theAlias) > 0 && theAlias[strlen(theAlias)-1] <= ' ') {
  567.                     theAlias[strlen(theAlias)-1] = '\0';
  568.                 }
  569.                 while (theAlias[strlen(theAlias)-1] == '\\') {
  570.                     theAlias[strlen(theAlias)-1] = ' ';
  571.                     if (fgets(str, 255, aliasfile) != (char *)NULL && !feof(aliasfile)) {
  572. #ifdef MULTIFINDER
  573.                         HUnlock(aliasHandle);
  574.                         SetHandleSize(aliasHandle, strlen(theAlias) + strlen(str) + 1);
  575.                         if (MemError() == noErr) {
  576.                             MoveHHi(aliasHandle);
  577.                             HLock(aliasHandle);
  578.                             newAlias = (char *) Strip((long int) *aliasHandle);
  579.                         } else {
  580.                             newAlias = (char *) NULL;
  581.                         }
  582. #else
  583.                         newAlias = realloc(theAlias, strlen(theAlias) + strlen(str) + 1);
  584. #endif
  585.                         if (newAlias == (char *) NULL) {
  586.                             fprintf(stderr, "Can't get string buffer for alias!");
  587.                             break;
  588.                         }
  589.                         theAlias = newAlias;
  590.                         strcat(theAlias, str);
  591.                         while(strlen(theAlias) > 0 && theAlias[strlen(theAlias)-1] <= ' ') {
  592.                             theAlias[strlen(theAlias)-1] = '\0';
  593.                         }
  594.                     }
  595.                 }
  596.                 if((nargs=getargs(theAlias, args)) > 2) {
  597.                     if(IUMagIDString(args[0], "alias", strlen(args[0])+1, 6) == 0 && 
  598.                         IUMagIDString(args[1], addr, strlen(args[1])+1, strlen(addr)+1) == 0) {
  599.                         gotalias = TRUE;
  600.                         for(i=2 ; i < nargs ; i++) {
  601.                             err &= sendit(argc, argv, args[i], remotes);
  602.                         }
  603. #ifdef MULTIFINDER
  604.                         DisposHandle(aliasHandle);
  605. #else
  606.                         free(theAlias);
  607. #endif
  608.                         theAlias = (char *) NULL;
  609.                         break;
  610.                     }
  611.                 }
  612.                 if (theAlias) {
  613. #ifdef MULTIFINDER
  614.                     DisposHandle(aliasHandle);
  615. #else
  616.                     free(theAlias);
  617. #endif
  618.                     theAlias = (char *) NULL;
  619.                 }
  620.             }
  621.             fclose(aliasfile);
  622.         }
  623.         if(gotalias == TRUE)
  624.             continue;
  625.         err &= sendit(argc, argv, *argvec, remotes);
  626.     }
  627.     /* dump remotes if necessary */
  628.     if ( strlen( remotes ) > 0 )
  629.         err &= sendone( argc, argv, remotes, TRUE );
  630.  
  631. #ifndef RMAIL
  632.  
  633.     if (strlen(mailcopy) > 0) {
  634.         /* wants copy of mail kept */
  635.         mkfilename( miscbuff, maildir, mailcopy );
  636.         if (*maildir != SEPCHAR)
  637.              mkfilename(mailsent, mcurdir, miscbuff);
  638.          else strcpy(mailsent, miscbuff);
  639.     
  640.         if ( debuglevel > 4 )
  641.            fprintf( stderr, "pcmail: copfile = %s\n", mailsent );
  642.         err &= sendone( argc, argv, mailsent, FALSE );
  643.     }
  644. #endif
  645.  
  646.     UNLINK( tfilename );
  647.     chdir( mcurdir );
  648. /*
  649.     closedir(spoolDir);
  650. */
  651.     return(err);
  652. }
  653.  
  654. /*
  655.     Get the current file-sequence number, and write out an updated one
  656. */
  657. void GetSequenceNumber(void)
  658. {
  659.     FILE   *tempfile;
  660.     char    miscbuff[255];
  661.     char    tfilename[255];
  662.     /* get sequence number */
  663.     mkfilename( miscbuff, confdir, SFILENAME);
  664.     if (*confdir != SEPCHAR)
  665.         /* make it an absolute pathname */
  666.         mkfilename(tfilename, mcurdir, miscbuff);
  667.     else strcpy(tfilename, miscbuff);
  668.  
  669.      if ( debuglevel > 4 )
  670.         fprintf( stderr, "pcmail: opening %s\n", tfilename ); /* */
  671.     tempfile = FOPEN( tfilename, "r", 't' );
  672.     if (tempfile != (FILE *)NULL) {
  673.         fscanf( tempfile, "%ld", &sequence );
  674.         fclose( tempfile );
  675.     }
  676.      else {
  677.          fprintf( stderr, "pcmail: can't find %s file, creating\n",
  678.                      tfilename );
  679.          sequence = 1;    /* start at 1 */
  680.      };
  681.  
  682.     /* update sequence number */
  683.     if ( debuglevel > 5 )
  684.         fprintf( stderr, "pcmail: new sequence # %ld\n", sequence );
  685.  
  686.     tempfile = FOPEN( tfilename, "w", 't' );
  687.     if (tempfile != (FILE *)NULL) {
  688.         /* BH-C */
  689.         if ( sequence > 9999 ) fprintf( tempfile, "%ld\n", 0 );
  690.         else
  691.         /* BH-C */
  692.         fprintf( tempfile, "%ld\n", sequence+1 );
  693.         fclose( tempfile );
  694.     }
  695.     /* sequence = sequence % 10000; BH-C */ /* Limit to four digits in filenames */
  696. }
  697.  
  698.  
  699. /* creates the chartime string */
  700. dodate(){        /* BH-C */
  701.  
  702.     MachineLocation        mLoc;
  703.     static char            *dw[7] = {"Sun","Mon","Tue","Wed",
  704.                                    "Thu","Fri","Sat"},
  705.                         *mth[12] = {"Jan","Feb","Mar","Apr",
  706.                                     "May","Jun","Jul","Aug",
  707.                                     "Sep","Oct","Nov","Dec"};
  708.     struct tm                *timeinfo;
  709.     char                    tmpst[128];
  710.     long                    GMTDelta,
  711.                         hours;
  712.     
  713.     timeinfo = localtime(&tloc);
  714.     sprintf(chartime, "%3.3s, %02.2d %3.3s %02.2d %02.2d:%02.2d:%02.2d",
  715.                 dw[timeinfo->tm_wday],
  716.                 timeinfo->tm_mday,
  717.                 mth[timeinfo->tm_mon],
  718.                 timeinfo->tm_year,
  719.                 timeinfo->tm_hour,
  720.                 timeinfo->tm_min,
  721.                 timeinfo->tm_sec);
  722.                 
  723.     ReadLocation(&mLoc);
  724.     GMTDelta = mLoc.gmtFlags.gmtDelta & 0x00ffffff;
  725.     if ( (GMTDelta >> 23) & 1 )
  726.         GMTDelta = GMTDelta | 0xff000000;
  727.     GMTDelta = GMTDelta / 60;
  728.     hours = GMTDelta / 60;
  729.     GMTDelta = GMTDelta + (40 * hours);
  730.     
  731.     if ( GMTDelta < 0 ) {
  732.         GMTDelta = -GMTDelta;
  733.         sprintf(tmpst,"-%04.4ld",GMTDelta);
  734.     } else
  735.         sprintf(tmpst,"+%04.4ld",GMTDelta);
  736.     
  737.     if ( mLoc.gmtFlags.dlsDelta ) {
  738.         if ( dlstimediff[0] > ' ' )
  739.             sprintf(chartime, "%s %s",chartime,dlstimediff);
  740.         else
  741.             sprintf(chartime, "%s %s%s",chartime,tmpst,dlstimediff);
  742.     } else {
  743.         if ( timediff[0] > ' ' )
  744.             sprintf(chartime, "%s %s",chartime,timediff);
  745.         else
  746.             sprintf(chartime, "%s %s%s",chartime,tmpst,timediff);
  747.     }
  748. }
  749.  
  750. char fpat1[] = "%c.%.7s9%04ld";
  751. char fpat1j[] = "%c.%.7s%c%04ld";
  752. char fpat2[] = "S %s %s %s - %s 0666 %s";
  753.  
  754.  
  755. /* sendone copies file plus headers to appropriate postbox
  756.    NB. we do headers here to allow flexibility later, for example
  757.    in being able to do bcc, per host service processing etc.
  758. */
  759. sendone(int argc, char **argv, char *address, int remote) {
  760.     register char     *cp;
  761. /* BH-C
  762.     struct tm        *timeinfo;
  763.     static char        *dw[7] = {"Sun","Mon","Tue","Wed",
  764.                               "Thu","Fri","Sat"},
  765.                     *mth[12] = {"Jan","Feb","Mar","Apr",
  766.                                 "May","Jun","Jul","Aug",
  767.                                 "Sep","Oct","Nov","Dec"};
  768. */
  769.                                 
  770.     char    icfilename[32];        /* local C. copy file */
  771.     char    ixfilename[32];        /* local X. xqt file */
  772.     char    idfilename[32];        /* local D. data file */
  773.     char    rxfilename[32];        /* remote X. xqt file */
  774.     char    rdfilename[32];        /* remote D. data file */
  775.      char    tmfilename[32];        /* temporary storage */
  776. #if MSDOS
  777.      char    cixfilename[32];        /* canonical ixfilename */
  778.      char    cidfilename[32];        /* canonical idfilename */
  779. #endif
  780.     char forwardto[256];
  781.     char *wherefrom;
  782.     MachineLocation mLoc;            /* BH-C */
  783.  
  784.      if ( remote ) {
  785.          /* sprintf all required file names */
  786.         sprintf( tmfilename, fpat1, 'C', viaremote,  sequence );
  787.         importpath( icfilename, tmfilename );
  788. #ifdef MSDOS
  789.          sprintf( cidfilename, fpat1, 'D', viaremote, sequence );
  790.         importpath( idfilename, cidfilename );
  791.         sprintf( cixfilename, fpat1, 'D', nodename, sequence );
  792.          importpath( ixfilename, cixfilename );
  793. #else
  794.         sprintf( tmfilename, fpat1, 'D', viaremote, sequence );
  795.         importpath( idfilename, tmfilename );
  796.         sprintf( tmfilename, fpat1, 'D', nodename, sequence );
  797.         importpath( ixfilename, tmfilename );
  798. #endif
  799.         sprintf( rdfilename, fpat1j, 'D', nodename, 'B', sequence );
  800.         sprintf( rxfilename, fpat1j, 'X', nodename, 'A', sequence );
  801.      }
  802.      else {
  803.         /* postbox file name */
  804.          if ( index( address, SEPCHAR ) == (char *)NULL )
  805.             /* BH-C v */
  806.              if ( mbox[0] ) {
  807.                  sprintf(idfilename,"%s:%s",maildir,address);
  808.                  mkfilename( idfilename, idfilename, mbox );
  809.              } else
  810.              /* BH-C ^ */
  811.             mkfilename( idfilename, maildir, address );
  812.         else
  813.             strcpy( idfilename, address );
  814.     }
  815.  
  816.     if ( debuglevel > 5 )
  817.          fprintf( stderr, "pcmail: sendone: %s\n", idfilename );
  818.  
  819.      if ( remote == FALSE ) {
  820.         if ( debuglevel > 5 )
  821.            fprintf( stderr, "pcmail: sendone: check for remote\n" );
  822.         /* check for forwarding */
  823.         if ( (mailfile = FOPEN( idfilename, "r", 't' )) != (FILE *)NULL ) {
  824.             cp = fgets( buf, BUFSIZ - 1, mailfile );
  825.             fclose( mailfile );
  826.             if (cp != (char *)NULL)
  827.                 if (strncmp( buf, FORWARD, 10 ) == 0) {
  828.                     strcpy( forwardto, buf+11 );
  829.                     if (strchr(forwardto, '!') != NULL || strchr(buf, '@') != NULL) {
  830.                         return( sendone( argc, argv, forwardto, TRUE ) );
  831.                     } else {
  832.                         return( sendone( argc, argv, forwardto, FALSE ) );
  833.                     } 
  834.                 }
  835.         }
  836.     }
  837.  
  838.     /* open mailfile */
  839.     if ( (mailfile = FOPEN( idfilename, "a", remote?'b':'t' )) == (FILE *)NULL ) {
  840.         fprintf( stdout, "pcmail: cannot append to %s\n", idfilename );
  841.         return( 0 );
  842.     }
  843.  
  844.     if ( debuglevel > 5 )
  845.         fprintf( stderr, "pcmail: append to mailfile\n" );
  846.  
  847.     tloc = time( (time_t *)NULL );
  848.     thetime = ctime(&tloc);
  849.      (void)strcpy(chartime, thetime);    /* make our own copy */
  850.      thetime = chartime;    /* and work with our own copy */
  851.     thetime[strlen(thetime)-1] = '\0';
  852.     /* timeinfo = localtime(&tloc);        BH-C */
  853.     
  854. #ifdef RMAIL
  855.     tempfile = FOPEN( tfilename, "r", 't' );
  856.     if ( tempfile == (FILE *)NULL) {
  857.         fprintf( stdout, "pcmail: can't re-open %s\n", tfilename );
  858.         return( 0 );
  859.     }
  860.     fgets( buf, BUFSIZ - 1, tempfile );
  861.     if ( strncmp( buf, "From ", 5 ) == 0 ) {
  862.         sscanf(buf, "From %s ", miscbuff);
  863. /*        printf("From [%s]\n", miscbuff); */
  864.     }
  865.     if (strlen(gotitfrom) > 0) {
  866.         wherefrom = gotitfrom;
  867.     } else {
  868.         wherefrom = mailserv;
  869.     }
  870.     if (strchr(miscbuff, '@') != NULL) {
  871.         fprintf(mailfile, "From %s %s", miscbuff, thetime);
  872.     } else {
  873.         fprintf(mailfile, "From %s!%s %s", wherefrom, miscbuff, thetime );
  874.     }
  875.     fputc( '\012', mailfile );
  876.     fprintf( mailfile, "Received: from %s by %s with UUPC;", wherefrom, domain);
  877.     fputc( '\012', mailfile );
  878.     
  879.     dodate();                        /* BH-C */
  880.     
  881. /* BH-C    
  882.     sprintf(chartime, "%3.3s, %02.2d %3.3s %02.2d %02.2d:%02.2d:%02.2d %s",
  883.                 dw[timeinfo->tm_wday],
  884.                 timeinfo->tm_mday,
  885.                 mth[timeinfo->tm_mon],
  886.                 timeinfo->tm_year,
  887.                 timeinfo->tm_hour,
  888.                 timeinfo->tm_min,
  889.                 timeinfo->tm_sec,
  890.                 timediff);
  891. */
  892.     fprintf( mailfile, "          %s", thetime);
  893.     fputc( '\012', mailfile );
  894. #else /* RMAIL */
  895.     fprintf( mailfile, "From %s %s", mailbox, thetime );
  896.     if ( remote )
  897.         fprintf( mailfile, " remote from %s", nodename );
  898.     fputc( '\012', mailfile );
  899.     fprintf( mailfile, "Received: by %s (pcmail);", domain);
  900.     fputc( '\012', mailfile );
  901.     
  902.     dodate();                        /* BH-C */
  903.     
  904. /* BH-C    
  905.     sprintf(chartime, "%3.3s, %02.2d %3.3s %02.2d %02.2d:%02.2d:%02.2d %s",
  906.                 dw[timeinfo->tm_wday],
  907.                 timeinfo->tm_mday,
  908.                 mth[timeinfo->tm_mon],
  909.                 timeinfo->tm_year,
  910.                 timeinfo->tm_hour,
  911.                 timeinfo->tm_min,
  912.                 timeinfo->tm_sec,
  913.                 timediff);
  914. */
  915.     fprintf( mailfile, "          %s", thetime);
  916.     fputc( '\012', mailfile );
  917.     fprintf( mailfile, "Date: %s", thetime);
  918.     fputc( '\012', mailfile );
  919.     /* add Date:, From: and Message-ID: headers */
  920.     fprintf( mailfile, "From: %s <%s@%s>", name, mailbox, domain );
  921.     fputc( '\012', mailfile );
  922.     fprintf( mailfile, "Message-Id: <%ld@%s>", sequence, domain );
  923.     fputc( '\012', mailfile );
  924.     
  925.     /* add To: headers */
  926.     fprintf(mailfile, "To:");
  927.     while(--argc > 0)
  928.         fprintf(mailfile, " %s", *++argv);
  929.     fputc('\012', mailfile);    /* better Ken? */
  930.  
  931.     if ( strlen( Subject ) > 0 ) {
  932.         fprintf( mailfile, "Subject: %s", Subject );
  933.         fputc( '\012', mailfile );
  934.     }
  935. #ifdef PCMAIL
  936.     /* add Message-Lines: and Content-Length: headers */
  937.     fprintf( mailfile, "X-Message-Lines: %ld", lines );
  938.     fputc( '\012', mailfile );
  939.     fprintf( mailfile, "Content-Length: %ld", bytes );
  940.     fputc( '\012', mailfile );
  941. #endif /* PCMAIL */
  942.     /* copy tempfile to postbox file */
  943.     tempfile = FOPEN( tfilename, "r", 't' );
  944.     if ( tempfile == (FILE *)NULL) {
  945.         fprintf( stdout, "pcmail: can't re-open %s\n", tfilename );
  946.         return( 0 );
  947.     }
  948. #endif /* RMAIL */
  949.     if (debuglevel > 4)
  950.        fprintf( stderr, "pcmail: copy tempfile %s to %s\n",
  951.                         tfilename, idfilename );
  952.  
  953.     while (fgets( buf, BUFSIZ - 1, tempfile ) != (char *)NULL) {
  954.         if ( strncmp( buf, "From ", 5 ) == 0 )
  955.             fputc( '>', mailfile );
  956.         cp = &buf[ strlen(buf)-1 ];
  957.         if ( *cp == '\n' )
  958.             *cp = '\0';
  959.         fputs( buf, mailfile );
  960.         fputc( '\012', mailfile );
  961.      }
  962.     if (!remote) fputc( '\012', mailfile );
  963.  
  964.     /* close files */
  965.     fclose( mailfile );
  966.     fclose( tempfile );
  967.  
  968.     /* all done unless going to remote via uucp */
  969.     /* must create the job control files */
  970.     if ( remote == TRUE ) {
  971.  
  972.         /* create remote X xqt file */
  973.         mailfile = FOPEN( ixfilename, "w", 'b' );
  974.         if     (mailfile == (FILE *)NULL) {
  975.             fprintf( stdout, "pcmail: cannot append to %s\n", ixfilename );
  976.             return( 0 );
  977.         }
  978.         fprintf( mailfile, "U %s %s", uucp, nodename );
  979.         fputc( '\012', mailfile );
  980.         fprintf( mailfile, "F %s", rdfilename );
  981.         fputc( '\012', mailfile );
  982.         fprintf( mailfile, "I %s", rdfilename );
  983.         fputc( '\012', mailfile );
  984.         fixaddress(address+1);
  985.         fprintf( mailfile, "C rmail %s", address );
  986.         fputc( '\012', mailfile );
  987.         fclose( mailfile );
  988.  
  989.         /* create local C copy file */
  990.         mailfile = FOPEN( icfilename, "w", 't' );
  991.         if     (mailfile == (FILE *)NULL) {
  992.             fprintf( stdout, "pcmail: cannot append to %s\n", icfilename );
  993.             return( 0 );
  994.         }
  995.  
  996. #if MSDOS
  997.          fprintf( mailfile, fpat2, cidfilename, rdfilename,
  998.                      uucp, cidfilename, uucp );
  999.          fputc( '\012', mailfile );
  1000.          fprintf( mailfile, fpat2, cixfilename, rxfilename,
  1001.                      uucp, cixfilename, uucp );
  1002.          fputc( '\012', mailfile );
  1003. #else
  1004.         fprintf( mailfile, fpat2, idfilename, rdfilename,
  1005.                     uucp, idfilename, uucp );
  1006.         fputc( '\012', mailfile );
  1007.         fprintf( mailfile, fpat2, ixfilename, rxfilename,
  1008.                     uucp, ixfilename, uucp );
  1009.         fputc( '\012', mailfile );
  1010. #endif
  1011.         fclose( mailfile );
  1012.  
  1013.     } /* if ( remote == TRUE ) */
  1014.  
  1015.     return( 1 );
  1016. }
  1017.  
  1018. /* Get address into percent form for rmail, and delete mailhost name */
  1019. fixaddress(char *address)
  1020. {
  1021.     char        temp[BUFSIZ];
  1022.     register    char    *p, *q, *r;
  1023.     
  1024.     q = address;
  1025.     temp[0] = '\0';
  1026.     while ( (p = index(q, ' ')) != NULL ) {
  1027.         *p = '\0';
  1028.         fixpercent(q);
  1029. #ifdef    PERCENT_ADDRS
  1030.         if ((r = strrchr(q, '@')) != NULL) *r = '%';
  1031.         if ((r = strrchr(q, '%')) != NULL ) {
  1032.             if (strcmp(r+1, mailserv) == 0) *r = '\0';
  1033.             if ((r = strrchr(q, '%')) != NULL) *r ='@';
  1034.         }
  1035. #else
  1036.         if ((r = strchr(q, '!')) != NULL) {
  1037.             if (strncmp(q, mailserv, (int)(r - q)) == 0)
  1038.                 q = r + 1;
  1039.         }
  1040. #endif    PERCENT_ADDRS
  1041.         strcat(temp, q);
  1042.         strcat(temp, " ");
  1043.         q = ++p;
  1044.     }
  1045.     /* do the last one */
  1046.     fixpercent(q);
  1047. #ifdef    PERCENT_ADDRS
  1048.     if ((r = strrchr(q, '@')) != NULL) *r = '%';
  1049.     if ((r = strrchr(q, '%')) != NULL ) {
  1050.         if (strcmp(r+1, mailserv) == 0) *r = '\0';
  1051.         else if (strncmp(r+1, mailserv, strlen(mailserv)) == 0 &&
  1052.                     strcmp(r+strlen(mailserv)+1, ".uucp") == 0) *r = '\0';
  1053.         if ((r = strrchr(q, '%')) != NULL) *r ='@';
  1054.     }
  1055. #else
  1056.         if ((r = strchr(q, '!')) != NULL) {
  1057.             if (strncmp(q, mailserv, (int)(r - q)) == 0)
  1058.                 q = r + 1;
  1059.         }
  1060. #endif    PERCENT_ADDRS
  1061.     strcat(temp, q);
  1062.     strcpy(address, temp);
  1063. }
  1064.  
  1065. #ifdef    PERCENT_ADDRS
  1066. /*    converts addresses to RFC 822 percent form
  1067.     %,@ takes precedence over ! e.g.,
  1068.     a!b!c%y@z -> c%b.uucp%a.uucp%y@z
  1069. */
  1070. fixpercent(char *addr)
  1071. {
  1072.     char    front[BUFSIZ], back[BUFSIZ];
  1073.     register char    *p;
  1074.  
  1075.     if ( (p = strrchr(addr, '%')) != NULL ||
  1076.          (p = strrchr(addr, '@')) != NULL) {
  1077.  
  1078.         *p = '\0';
  1079.         if (strchr(addr, '!') != NULL) fixpercent(addr);
  1080.         if (strchr(p+1, '!') != NULL) fixpercent(p+1);
  1081.         *p = '%';
  1082.     }
  1083.     else if ( (p = strchr(addr, '!')) != NULL) {
  1084.         *p++ = '\0';
  1085.         strcpy(front, addr);
  1086.         strcpy(back, p);
  1087.         fixpercent(back);
  1088.         strcpy(addr, back);
  1089.         strcat(addr, "%");
  1090.         strcat(addr, front);
  1091.         if (strchr(front, '.') == NULL) {
  1092.             strcat(addr, ".uucp");
  1093.         }
  1094.     }
  1095. }
  1096. #else
  1097. /*    converts addresses to uucp ! form
  1098.     %,@ takes precedence over ! e.g.,
  1099.     a!b!c%y@z -> z!y!a!b!c
  1100. */
  1101. fixpercent(char *addr)
  1102. {
  1103.     char    front[BUFSIZ];
  1104.     register char    *p;
  1105.  
  1106.     if ( (p = strrchr(addr, '@')) != NULL ||
  1107.          (p = strrchr(addr, '%')) != NULL) {
  1108.         *p = '\0';
  1109.         strcpy(front, p+1);
  1110.         strcat(front, "!");
  1111.         fixpercent(addr);
  1112.         strcat(front, addr);
  1113.         strcpy(addr, front);
  1114.     }
  1115. }
  1116. #endif    PERCENT_ADDRS
  1117.  
  1118. #ifndef AMIGA
  1119. #ifdef RMAIL
  1120. rnews(int argc, char *argv[])
  1121. {
  1122.     struct tm    *thetm;
  1123.     char    filename[132];
  1124.     char    format[128];
  1125.     FILE     *f;
  1126.     char    buf[BUFSIZ];
  1127.  
  1128.     static int count = 0;
  1129.     int gotBytes;
  1130.  
  1131.     tloc = time( (time_t *)NULL );
  1132.     thetime = ctime(&tloc);
  1133.     tloc = time( (time_t *)NULL );
  1134.  
  1135.     thetm = localtime( &tloc );
  1136.  
  1137.     /* mkfilename( format, spooldir, NEWSDIR );    */
  1138.     sprintf( filename, NEWSDIR,
  1139.         thetm->tm_year % 100, thetm->tm_mon+1,
  1140.         thetm->tm_mday, thetm->tm_hour,
  1141.         thetm->tm_min,  thetm->tm_sec,  count
  1142.         );
  1143.  
  1144.     count++;
  1145.  
  1146.     if ( debuglevel > 5 )
  1147.         fprintf( stderr, "rnews: %s\n", filename );
  1148.  
  1149.     if ( (f = FOPEN( filename, "w", 'b' )) == (FILE *)NULL ) {
  1150.         fprintf( stderr, "rnews: can't open %s %d\n", filename, errno );
  1151.         return( 0 );
  1152.     }
  1153.  
  1154.     while ( (gotBytes = fread( buf, 1, BUFSIZ, stdin)) != 0) {
  1155.         fwrite( buf, 1, gotBytes, f );
  1156. #ifdef MULTIFINDER
  1157.         Check_Events(0);
  1158. #endif
  1159.     }
  1160.  
  1161.     fclose( f );
  1162.     return (1);
  1163. }
  1164.  
  1165. #endif /* RMAIL */
  1166. #endif /* AMIGA */
  1167.  
  1168.